home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
376-400
/
376
/
plotter
/
src
/
diskussion.c
< prev
next >
Wrap
Text File
|
1995-03-14
|
11KB
|
456 lines
/********************************************************************/
/**** ****/
/**** ****/
/**** Program : Diskussion.c ****/
/**** ****/
/**** Version : 03.71 ****/
/**** ****/
/**** Erstversion : 04.11.1989 ****/
/**** ****/
/**** Letzte Änderung : 05.08.1990 ****/
/**** ****/
/**** Compiliert mit : siehe MAKEFILE ****/
/**** ****/
/**** Gelinkt mit : siehe MAKEFILE ****/
/**** ****/
/********************************************************************/
/**** ****/
/**** ****/
/**** Copyright by Rüdiger Dreier ****/
/**** ****/
/**** ****/
/********************************************************************/
#ifdef DEBUG
#include "Plotter.h"
#include <proto/tool.h>
#endif
#include <stdio.h>
#include <string.h>
#include "Plotter.h"
#include <string.h>
#include <stdlib.h>
#define SCHRITTE 200
DOUBLE BestF,BestX;
char AusgabeString[125]; /* Höchster auftretender Wert : 123 */
#undef GRENZE1
#define GRENZE1 0.0002
#define GRENZE2 0.0000002
#define NONULL HUGE
LONG ypos_Diskussion;
LONG xpos_Diskussion;
VOID discuss(char *string,DOUBLE l,DOUBLE r,int modus,unsigned short sub)
{
double i,var,fl,fr,add,fwert,flp,frp,Zugabe,h,vzl,vzr;
char text[5];
char NoNull=0;
StartBlock=Init_Mem(string); /* Struktur für die zu untersuchende Funktion */
if(!StartBlock)return;
MatheFehler=Init_Block(StartBlock);
MatheFehler|=PreCalc(StartBlock,Konstantenstart);
switch(modus)
{
case 0:
{
Print(RastPort,DISK_NULLST,FARBE3,10,ypos_Diskussion);
break;
}
case 1:
{
Print(RastPort,DISK_EXTREMST,FARBE3,10,ypos_Diskussion);
break;
}
case 2:
{
Print(RastPort,DISK_WENDEST,FARBE3,10,ypos_Diskussion);
break;
}
};
add=Div(Sub(r,l),SCHRITTE);
l=Sub(l,add); /* Die Grenzen werden etwas erweitert, um Randextrema */
r=Add(r,add); /* zu erfassen */
Zugabe=Div(add,SCHRITTE/2);
Calc_P(&fl,StartBlock,&l);
flp=Abs(fl);
for(i=Add(l,add);Cmp(i,r)<=0;i=Add(i,add))
{
Calc_P(&fr,StartBlock,&i);
frp=Abs(fr);
if((Tst(fl)!=Tst(fr)) || (Cmp(frp,GRENZE1)==-1 && Tst(flp)))
{
/* Eine Nullstelle ! */
if(Tst(fl)!=Tst(fr))
{
var=Nullstelle(Sub(i,add),i);
i=Add(i,add);
Calc_P(&fr,StartBlock,&i);
frp=Abs(fr);
}
else
{
var=Nullstelle2(Sub(i,add),i);
if(Cmp(var,HUGE)==0)NoNull=1;
if(Cmp(Add(var,Zugabe),i)>=1)
{
while(Cmp(frp,GRENZE1)==-1 && Cmp(i,r)==-1)
{
i=Add(i,add);
MatheFehler=Calc_P(&fr,StartBlock,&i);
frp=Abs(fr);
}
}
}
berechnen(&fwert,Formeln[sub],&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
MatheFehler=Calc_P(&h,StartBlock,&var);
if(MatheFehler!=0 || Cmp(Abs(h),GRENZE2)==1)
{
NoNull=1;
}
if(modus>0)
{
h=Sub(var,GRENZE2);
Calc_P(&vzl,StartBlock,&h); /* f(x) links neben Nullstelle */
h=Add(var,GRENZE2);
Calc_P(&vzr,StartBlock,&h); /* f(x) rechts neben Nullstelle */
if(Tst(vzl)==Tst(vzr))
{
NoNull=1;
}
}
if(!NoNull)
{
switch(modus)
{
case 0:
{
/* f(x) */
text[0]=0;
/*strcpy(text,"");*/
break;
}
case 1:
{
/* f'(x) */
if(Cmp(fl,fr)==-1)
{
strcpy(text,"Min");
}
else
{
strcpy(text,"Max");
}
break;
}
case 2:
{
/* f''(x) */
if(Cmp(fl,fr)==-1)
{
strcpy(text,"R-L");
}
else
{
strcpy(text,"L-R");
}
break;
}
}
TextAusgabe(var,fwert,text);
}
}
NoNull=0;
fl=fr;
flp=frp;
}
Free_Block(StartBlock); /* Speicher freigeben */
}
/* Bestimmt Nullstelle, wenn Vorzeichenwechsel vorliegt */
DOUBLE Nullstelle(l,r)
double l,r;
{
double i,fl,fr,fm,nl,nr;
char tiefe=0;
nl=l;
nr=r;
if(tiefe==0)
{
BestF=100.0;
BestX=l;
}
MatheFehler=Calc_P(&fl,StartBlock,&l);
if(MatheFehler==0&&Tst(fl)==0)return(l);
MatheFehler=Calc_P(&fr,StartBlock,&r);
if(MatheFehler==0&&Tst(fr)==0)return(r);
/* Intervallschachtelung */
while(tiefe<=40)
{
i=Div(Add(nl,nr),2.000);
MatheFehler=Calc_P(&fm,StartBlock,&i);
if(MatheFehler==0)
{
if(Cmp(Abs(fm),4000.0)==1)
{
tiefe=42; /* Wird wohl keine Nullstelle sein */
}
if(Cmp(Abs(fm),BestF)==-1L)
{
BestF=Abs(fm); /* Besser als bisheriger Wert */
BestX=i;
}
}
if(Tst(fl)!=Tst(fm))
{
nr=i;
}
else
{
nl=i;
}
tiefe++;
}
if(MatheFehler!=0 && tiefe==41)
{
/* Ist die Funktion nur für einen Randwert des ursprünglichen Bereichs l-r */
/* definiert (z.B. sqr mit l=-0.5 und r=0.0), dann wird immer ein Fehler */
/* beim Berechnen des Funktionswertes für die Mitte festgestellt. */
MatheFehler=Calc_P(&fm,StartBlock,&r);
if(MatheFehler==0&&Cmp(Abs(fm),GRENZE2)==-1L)
{
i=r; /* Eine Näherung */
}
else
{
MatheFehler=Calc_P(&fm,StartBlock,&l);
if(MatheFehler==0 && Cmp(Abs(fm),GRENZE2)==-1L)
{
i=l; /* Eine Näherung */
}
}
}
if(Cmp(Abs(fm),BestF)==1)i=BestX;
return(i);
}
/* Bestimmt Nullstelle, wenn kein VZ vorliegt */
DOUBLE Nullstelle2(l,r)
double l,r;
{
double i,fl,fr,fm,flp,frp,fmp,add;
add=(Sub(r,l));
Calc_P(&fl,StartBlock,&l);
flp=Abs(fl);
Calc_P(&fr,StartBlock,&r);
frp=Abs(fr);
/* Sorgt dafür, daß r außerhalb des Bereiches unter GRENZE1 liegt */
if(Cmp(frp,GRENZE1)==-1)
{
/* rechte Stelle suchen, für die f(x)>GRENZE1 */
while(Cmp(frp,GRENZE1)==-1)
{
r=Add(r,add);
Calc_P(&fr,StartBlock,&r);
frp=Abs(fr);
if(Tst(fl)!=Tst(fr))
{
l=Nullstelle(l,r);
return(l);
}
}
}
add=Div(Sub(r,l),SCHRITTE);
i=Add(l,add);
Calc_P(&fm,StartBlock,&i);
fmp=Abs(fm);
/* Tastet sich von links heran, solange wie die F-Werte immer kleiner werden */
while(Cmp(flp,fmp)==1)
{
l=i;
flp=fmp;
i=Add(i,add);
Calc_P(&fm,StartBlock,&i);
fmp=Abs(fm);
if(Tst(fl)!=Tst(fr))
{
l=Nullstelle(l,r);
return(l);
}
}
i=Sub(r,add);
Calc_P(&fm,StartBlock,&i);
fmp=Abs(fm);
/* Tastet sich entsprechend von rechts heran */
while(Cmp(frp,fmp)==1&&Cmp(r,l)==1)
{
r=i;
frp=fmp;
i=Sub(i,add);
Calc_P(&fm,StartBlock,&i);
fmp=Abs(fm);
if(Tst(fl)!=Tst(fr))
{
l=Nullstelle(l,r);
return(l);
}
}
if(Cmp(Min(flp,frp),GRENZE2)==-1)
{
if(Cmp(flp,frp)==1)
{
return(r);
}
else
{
return(l);
}
}
else
{
return(NONULL);
}
}
VOID TextAusgabe(DOUBLE x,DOUBLE y,char *string)
{
char ZwischenString[50];
char xc[10],yc[10];
LONG max_x=562;
SHORT *a;
if(Groesse)
{
max_x=994;
}
/* Besser: min(abs(xmn,xmp)) nehmen */
if(Cmp(Abs(x),Div(xmp,1000.0))==-1)x=0.0000; /* Runden */
if(Cmp(Abs(y),Div(ymp,1000.0))==-1)y=0.0000;
UmwFtoS(xc,&x,3);
Laenge(xc,9);
UmwFtoS(yc,&y,3);
Laenge(yc,9);
/*strcpy(ZwischenString,"(");*/
a=(SHORT *)ZwischenString;
*a=0x2800;
strcat(ZwischenString,xc);
strcat(ZwischenString,"/");
strcat(ZwischenString,yc);
strcat(ZwischenString,")");
strcat(ZwischenString,string);
if(xpos_Diskussion>=max_x)
{
xpos_Diskussion=146;
ypos_Diskussion+=10;
}
Print(RastPort,ZwischenString,FARBE3,xpos_Diskussion,ypos_Diskussion);
xpos_Diskussion+=216; /* 29*8 */
}
VOID TextAusgabe2(char *string)
{
LONG SPos=0;
LONG Max_Zeichen=53;
if(Groesse)
{
Max_Zeichen=107;
}
do
{
mid(AusgabeString,string,SPos,Max_Zeichen);
SPos+=Max_Zeichen;
Print(RastPort,AusgabeString,FARBE3,146L,ypos_Diskussion);
ypos_Diskussion+=10;
}
while(AusgabeString[0]!=0);
ypos_Diskussion-=10;
xpos_Diskussion=146;
}
/* Fügt VOR dem string so viele Leerzeichen ein, */
/* daß der String laenge lang wird */
VOID __asm Laenge(register __a0 char *string,
register __d0 int laenge)
{
SHORT a;
SHORT i;
char HILFE[18];
a=laenge-(strlen(string));
for(i=0;i<a;i++)
{
HILFE[i]=32;
}
HILFE[i]=0;
strcat(HILFE,string);
strcpy(string,HILFE);
}
VOID __asm Full_Discussion(register __d0 USHORT sub)
{
Loeschen();
strcpy(Abgeleitet[0],DISK_FOR);
UmwFtoS(&Abgeleitet[0][strlen(Abgeleitet[0])],&xmn,3);
strcat(Abgeleitet[0],"|");
UmwFtoS(&Abgeleitet[0][strlen(Abgeleitet[0])],&xmp,3);
strcat(Abgeleitet[0],"]");
Print(RastPort,Abgeleitet[0],FARBE3,10L,15L);
ypos_Diskussion=35;
/* Bilden der 1. Ableitung */
strcpy(Formeln[10],Formeln[sub]);
strcpy(Abgeleitet[0],Ableiten(Formeln[10]));
/* Bilden der 2. Ableitung */
strcpy(Formeln[10],Abgeleitet[0]);
strcpy(Abgeleitet[1],Ableiten(Formeln[10]));
KoordinatenKreuz_gezeichnet=FALSE;
Print(RastPort,"f (x) =",FARBE3,10L,ypos_Diskussion);
TextAusgabe2(Formeln[sub]);
discuss(Formeln[sub],xmn,xmp,0,sub);
ypos_Diskussion+=15;
Print(RastPort,"f' (x) =",FARBE3,10L,ypos_Diskussion);
TextAusgabe2(Abgeleitet[0]);
discuss(Abgeleitet[0],xmn,xmp,1,sub);
ypos_Diskussion+=15;
Print(RastPort,"f''(x) =",FARBE3,10L,ypos_Diskussion);
TextAusgabe2(Abgeleitet[1]);
discuss(Abgeleitet[1],xmn,xmp,2,sub);
}